package org.gnf.umls;

import gov.nih.nlm.kss.models.meta.concept.Concept;
import gov.nih.nlm.kss.models.meta.concept.ConceptId;
import gov.nih.nlm.kss.models.meta.concept.SemType;
import gov.nih.nlm.kss.models.meta.concept.SemTypeGroup;
import gov.nih.nlm.kss.models.sem.units.SemGroup;
import gov.nih.nlm.kss.models.sem.units.SemGroupGroup;
import gov.nih.nlm.kss.models.sem.units.SemNetId;

import java.net.MalformedURLException;
import java.rmi.RemoteException;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.xml.rpc.ServiceException;


/**
 * This representation is designed to enable the semantic comparison of terms.  It is centered on the term,
 * allowing for the possibility of polysemy by enabling the term to be connected to multiple concepts
 * @author benjamgo
 *
 */
public class SemanticTerm {

	public String term;
	public List<Concept> concepts;

	public SemanticTerm(String t){
		term = t;
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		//create a table of terms that match mesh 2008 concepts
		//get the tags for pubmed docs
		/*
		Set<String> pmids = TagDb.getDistinctConnoPostedPmids(1000000);		
		Set<String> tags = new HashSet<String>();
		Connotea codb = new Connotea();
		for(String pmid : pmids){
			tags.addAll(codb.getDistinctConnoPostedTagsByPmid(pmid));		
		}
		ConceptDb cdb = new ConceptDb(false);
		Set<String> already = cdb.exactMesh2008MatchTestedTerms();
		tags.removeAll(already);

		int total = tags.size();

		int c = 0;
		for(String t : tags){
			c++;
			System.out.println("Inserting "+t+" n = "+c+" of "+total);
			SemanticTerm s = new SemanticTerm(t);
			s.setConceptsFromUmlsExactMatchMesh2008();
			if(s.concepts!=null&&s.concepts.size()>0){
				s.insertRecord();
			}else{
				cdb.insertUnMatchedTerm(s.term);
				System.out.println(t+" - undefined");
			}
		}
		cdb.closeConnection();
		 */		


//		try again for connotea tags without a match - umls service improved
		//add in the concepts for the chemical records
//		String[] mesh_vocabs = {"MSH","MSHCZE","MSHDUT","MSHFIN","MSHFRE","MSHGER","MSHITA","MSHJPN","MSHPOR","MSHRUS","MSHSPA","MSHSWE"};
//
//		DatabaseUtil db = new DatabaseUtil("/usr/local/db_config_bibliotech2");	
//		ConceptDb cdb = new ConceptDb(false);
//		try {
//			int c = 0;
//			PreparedStatement update_exactM_cui = db.getPreparedStatement(
//		//	"update term_exactM_concept set cui = ? where term = ?");
//			"update term_exactM_concept set doublechecked = ? where term = ?");
//
//			ResultSet missing = db.executeQuery(
//			"select distinct term_exactM_concept.term from term_exactM_concept, conno_tags_clean, conno_posts_tags_clean, conno_posts_clean where term = value and mesh_descriptor_id = 'none' and cui = 'none' and term not like '%*%' and conno_tags_clean.id = conno_posts_tags_clean.tag_id and conno_posts_clean.id = conno_posts_tags_clean.post_id and conno_posts_clean.pmid > 0 and batch_update = -1 and batch_create = -1");
////			produced 16713 terms when run on April 28, 2008
////			reduced to 15087 when this completed on April 30, 2008			
//			boolean wait = true;
//			String start = "SSCAP";//13201
//			while(missing.next()){
//				c++;
//				String term = missing.getString("term");
//				update_exactM_cui.clearParameters();
//				update_exactM_cui.setInt(1, 1);
//				update_exactM_cui.setString(2, term);
//				update_exactM_cui.executeUpdate();	
//				System.out.println(c+" "+term);
//				/*	
//				if(term.equals(start)){
//					wait = false;
//				}
//				if(!wait){
//					System.out.println(c+" "+term);
//					List<ConceptId> cuids = Client.getCUIdsByExactMatch(term, null, null);
//					if(cuids!=null&&cuids.size()>0){
//						System.out.println("found concepts");
//						for(ConceptId con : cuids){
//							String cui = con.getCUI();
//							String cname = con.getCN();
//							//insert the concept
//							cdb.insertUmlsConcept(cui, cname);
//							//insert the connection
//							update_exactM_cui.clearParameters();
//							update_exactM_cui.setString(1, cui);
//							update_exactM_cui.setString(2, term);
//							update_exactM_cui.executeUpdate();					
//							//insert the types
//							List<Concept> cls = Client.getConceptProperties(cui);
//							for(Concept concept : cls){
//								SemTypeGroup stgroup = concept.getSTYs();
//								for(Object st :stgroup.getContents()){
//									SemType stype = (SemType)st;
//									String sui = stype.getTUI();
//									String sname = stype.getSTY();
//									//insert semantic type record if not present
//									cdb.insertSemanticType(sui, sname);
//									//insert connection from concept to type
//									cdb.insertConceptType(cui, sui);		
//								}
//							}
//						}
//					}else{
//						System.out.println("no concepts found");
//					}
//				}
//		*/		
//			}
//			cdb.closeConnection();
//		} catch (SQLException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		} 
	/*	catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ServiceException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
*/

		/*		
		//add in the concepts for the chemical records
		String[] mesh_vocabs = {"MSH","MSHCZE","MSHDUT","MSHFIN","MSHFRE","MSHGER","MSHITA","MSHJPN","MSHPOR","MSHRUS","MSHSPA","MSHSWE"};

		DatabaseUtil db = new DatabaseUtil("/usr/local/db_config_bibliotech2");	
		ConceptDb cdb = new ConceptDb(false);
		try {
			int c = 0;
	//		PreparedStatement insert_chem_cui = db.getPreparedStatement("insert into chemical_concept values(?,?)");
			PreparedStatement update_chem_cui = db.getPreparedStatement("update chemical_concept set cui = ? where chemical_id = ?");

			ResultSet missing = db.executeQuery(
	//		"select chemical, chemical_id from mesh_chemical where chemical_id not in (select chemical_id from chemical_concept);");
			"select mesh_chemical.chemical, mesh_chemical.chemical_id from mesh_chemical, chemical_concept where chemical_concept.chemical_id = mesh_chemical.chemical_id and cui = 'none'");

			while(missing.next()){
				c++;
				String chemical_id = missing.getString("chemical_id");
				String chemical = missing.getString("chemical");
				System.out.println(c+" "+chemical);
				List<ConceptId> cuids = Client.getCUIdsByExactMatch(chemical, mesh_vocabs, null);
				if(cuids==null||cuids.size()< 1){
					cuids = Client.getCUIdsByNormString(chemical, null, null);
				}
				if(cuids!=null&&cuids.size()>0){
					System.out.println("found concepts");
					for(ConceptId con : cuids){
						String cui = con.getCUI();
						String cname = con.getCN();
						//insert the concept
						cdb.insertUmlsConcept(cui, cname);
						//insert the connection
					//	insert_chem_cui.clearParameters();
					//	insert_chem_cui.setString(1, chemical_id);
					//	insert_chem_cui.setString(2, cui);
					//	insert_chem_cui.executeUpdate();

						update_chem_cui.clearParameters();
						update_chem_cui.setString(1, cui);
						update_chem_cui.setString(2, chemical_id);
						update_chem_cui.executeUpdate();

						//insert the types
						List<Concept> cls = Client.getConceptProperties(cui);
						for(Concept concept : cls){
							SemTypeGroup stgroup = concept.getSTYs();
							for(Object st :stgroup.getContents()){
								SemType stype = (SemType)st;
								String sui = stype.getTUI();
								String sname = stype.getSTY();
								//insert semantic type record if not present
								cdb.insertSemanticType(sui, sname);
								//insert connection from concept to type
								cdb.insertConceptType(cui, sui);		
							}
						}
					}
				}else{
					System.out.println("no concepts found");
				}
			}
			cdb.closeConnection();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ServiceException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		 */

		/*	
		// fix missing in downloaded mesh terms
		DatabaseUtil db = new DatabaseUtil("/usr/local/db_config_bibliotech2");	

		try {
			ResultSet wrong = db.executeQuery(
					"select * from meshFromEutils where descriptor not in (select descriptor_name from mesh2008_descriptor)");
			while(wrong.next()){
				String descriptor_id = wrong.getString("descriptor_id");
				String descriptor = wrong.getString("descriptor");
				System.out.println(descriptor);
				List<ConceptId> cuids = Client.getCUIdsByExactMatch(descriptor, null, "ENG");
				if(cuids==null||cuids.size()< 1){
					cuids = Client.getCUIdsByNormString(descriptor, null);
				}
				if(cuids==null||cuids.size()< 1){
					cuids = Client.getCUIdsByWords(descriptor, null);
				}
				if(cuids!=null&&cuids.size()>0){
					System.out.println("found concepts");
					for(ConceptId con : cuids){
						String q = con.getCUI();
						ResultSet right = db.executeQuery1(
								"select descriptor_name from mesh2008_descriptor, descriptor_concept " +
								"where mesh2008_descriptor.descriptor_id = descriptor_concept.descriptor_id " +
								"and cui = '"+q+"'");
						if(right.next()){
							String newd = right.getString("descriptor_name");
							PreparedStatement p = db.getPreparedStatement("update meshFromEutils set descriptor = ? where descriptor_id = ?");
							p.clearParameters();
							p.setString(1, newd);
							p.setString(2,descriptor_id);
							p.executeUpdate();
							p.close();
							System.out.println("\t found "+newd+" for "+q );
						}else{
							System.out.println("couldn't match concept "+q);
						}
					}
				}else{
					System.out.println("no concepts found");
				}
			}

		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ServiceException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		 */
		//fix missing using web services- some concepts weren't assigned in mesh2008 file
		/*	
		DatabaseUtil db = new DatabaseUtil("/usr/local/db_config_bibliotech2");	
		try {
			String[] vocabs = {"MSH"};
			ResultSet missing = db.executeQuery("select mesh2008_descriptor.* from mesh2008_descriptor where mesh2008_descriptor.descriptor_id not in (select distinct(descriptor_id) from descriptor_concept)");
			int count = 0;
			Set<String> notexact = new HashSet<String>();
			Set<String> notmatched = new HashSet<String>();
			while(missing.next()){
				count++;
				String dui = missing.getString("descriptor_id");		
				String dn = missing.getString("descriptor_name");
			//	System.out.println(dn+" "+dui+" ");
				List<ConceptId> cuids = Client.getCUIdsBySabCode(dui, vocabs);
				if(cuids==null||cuids.size()<1){
					notexact.add(dui);
					cuids = Client.getCUIdsByExactMatch(dn, null, null);
				}
				if(cuids!=null&&cuids.size()>0){
					for(ConceptId cuid : cuids){
						String cui = cuid.getCUI();
						String cname = cuid.getCN();
						//add the concept records
						cdb.insertUmlsConcept(cui, cname);
						//add the connection
						cdb.insert2008DescriptorConcept(dui,cui);
						//add the types for the concepts
						List<Concept> conceptprops = Client.getConceptProperties(cui);
					//	System.out.println(dn+" "+dui+" "+cui+" "+cname);
						for(Concept c : conceptprops){
							SemTypeGroup stgroup = c.getSTYs();
							for(Object st :stgroup.getContents()){
								SemType stype = (SemType)st;
								String sui = stype.getTUI();
								String sname = stype.getSTY();
								//insert semantic type record if not present
								cdb.insertSemanticType(sui, sname);

								//insert connection from concept to type
								cdb.insertConceptType(cui, sui);
								System.out.println(count+" "+dn+" "+dui+" "+cui+" "+cname+" "+sui+" "+sname);
							}
						}
					}
				}else{
					notmatched.add(dui);
					System.out.println("Nothing found for: "+dn+" "+dui);
				}
			}
			System.out.println("tried: "+count+"\n not exact "+notexact+"\n not matched "+notmatched);
		}
		catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ServiceException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		 */
		/*
		Set<String> tags = getUnMatchedConnoteaPmidTags();
		int total = tags.size();
		ConceptDb cdb = new ConceptDb(false);
		int c = 0;
		for(String t : tags){
			c++;
			System.out.println("Inserting "+t+" n = "+c+" of "+total);
			SemanticTerm s = new SemanticTerm(t);
			s.setConceptsFromUmlsExactMatch();
			if(s.concepts!=null&&s.concepts.size()>0){
				s.insertRecord();
			}else{
				cdb.insertUnMatchedTerm(s.term);
				System.out.println(t+" - undefined");
			}
		}
		cdb.closeConnection();
		 */
	}

	


	public void setConceptsFromUmlsExactMatchMesh2008(){
		String[] vocabs = {"MSH"};
		try {
			List<ConceptId> cuids = Client.getCUIdsByExactMatch(term, vocabs, null);
			for(ConceptId cuid : cuids){
				if(concepts == null){
					concepts = Client.getConceptProperties(cuid.getCUI(), false, vocabs);
				}else{
					concepts.addAll(Client.getConceptProperties(cuid.getCUI(), false, vocabs));
				}
			}
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ServiceException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}	

	public void setConceptsFromUmlsExactMatch(){
		try {
			List<ConceptId> cuids = Client.getCUIdsByExactMatch(term, null, null);
			for(ConceptId cuid : cuids){
				if(concepts == null){
					concepts = Client.getConceptProperties(cuid.getCUI(), false, null);
				}else{
					concepts.addAll(Client.getConceptProperties(cuid.getCUI(), false, null));
				}
			}
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ServiceException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
/*
	public void insertUnMatchedTerm(){
		String insert = "insert into term_exactM_concept values(?,'none')";
		DatabaseUtil db = new DatabaseUtil("/usr/local/db_config_bibliotech2");	
		try {
			PreparedStatement insert_term_concept = db.getPreparedStatement(insert);
			insert_term_concept.setString(1, term);
			insert_term_concept.executeUpdate();
			db.closeConnection();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
*/
	/**
	 * Inserts bits of the current instance of this object into a local database
	 */
/*
	public void insertMesh2008Record(){
		ConceptDb cdb = new ConceptDb(false);

		for(Concept concept : concepts){
			String cui = concept.getCUI();
			String cname = concept.getCN();
			//insert concept record if not present
			cdb.insertUmlsConcept(cui, cname);
			//insert connection from term to concept
			cdb.insertTermExactMConceptMesh2008(term, cui);

			SemTypeGroup stgroup = concept.getSTYs();
			for(Object st :stgroup.getContents()){
				SemType stype = (SemType)st;
				String sui = stype.getTUI();
				String sname = stype.getSTY();
				//insert semantic type record if not present
				cdb.insertSemanticType(sui, sname);

				//insert connection from concept to type
				cdb.insertConceptType(cui, sui);
*/
				/*		
				 * this was a bug.  a few concepts might end up in multiple groups, but a type should
				 * definitely not - construct this little table separately..
				SemGroupGroup sgroup = concept.getSGs();
				for(Object stg :sgroup.getContents()){
					SemGroup group = (SemGroup)stg;
					String abbr = group.getAbbrev();
					String gname = group.getName();
					//insert semantic group record of not present
					cdb.insertSemanticGroup(abbr, gname);
					//insert connection from type to group if not present
					cdb.insertTypeGroup(sui, abbr);
				}
				 */			
//			}
//		}
//		cdb.closeConnection();
//	}	

	/**
	 * Inserts bits of the current instance of this object into a local database

	public void insertRecord(){
		ConceptDb cdb = new ConceptDb(false);

		for(Concept concept : concepts){
			String cui = concept.getCUI();
			String cname = concept.getCN();
			//insert concept record if not present
			cdb.insertUmlsConcept(cui, cname);
			//insert connection from term to concept
			cdb.insertTermExactMConcept(term, cui);

			SemTypeGroup stgroup = concept.getSTYs();
			for(Object st :stgroup.getContents()){
				SemType stype = (SemType)st;
				String sui = stype.getTUI();
				String sname = stype.getSTY();
				//insert semantic type record if not present
				cdb.insertSemanticType(sui, sname);

				//insert connection from concept to type
				cdb.insertConceptType(cui, sui);
*/
				/*		
				 * this was a bug.  a few concepts might end up in multiple groups, but a type should
				 * definitely not - construct this little table separately..
				SemGroupGroup sgroup = concept.getSGs();
				for(Object stg :sgroup.getContents()){
					SemGroup group = (SemGroup)stg;
					String abbr = group.getAbbrev();
					String gname = group.getName();
					//insert semantic group record of not present
					cdb.insertSemanticGroup(abbr, gname);
					//insert connection from type to group if not present
					cdb.insertTypeGroup(sui, abbr);
				}
				 */			
//			}
//		}
//		cdb.closeConnection();
//	}

	/*
	 * 

	 		//get the groups
		DatabaseUtil d = new DatabaseUtil("/usr/local/db_config_bibliotech2");	
		ResultSet r;
		try {
			r = d.executeQuery("select * from umls_semantic_group");
		while(r.next()){
			String g = r.getString("name");
			String a = r.getString("abbr");
			List<SemNetId> sids = Client.getTypesOfGroup(g);
			for(SemNetId sid : sids){
				//System.out.println(sid.getKey()+"\t"+sid.getName());
				//insert connection from type to group if not present
				String sui = sid.getKey().substring(sid.getKey().lastIndexOf('.')+1);
				cdb.insertTypeGroup(sui, a);
				System.out.println("s "+sui+" "+sid.getName()+" a "+a);
			}
		}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}


	 */

	/**
	 Queries:
	 Get semantic type counts of term occurences
		select umls_semantic_type.name, count(*) 
		from umls_semantic_type, term_exactM_concept, umls_concept_s_type  
	 	where term_exactM_concept.cui = umls_concept_s_type.cui  
	 	and umls_concept_s_type.sui = umls_semantic_type.sui 
	 	group by umls_semantic_type.name;
	Get semantic group counts of term occurences
		select umls_semantic_group.name, count(*) 
		from umls_semantic_group, umls_semantic_type, term_exactM_concept, umls_concept_s_type, umls_s_type_s_group   
	 	where term_exactM_concept.cui = umls_concept_s_type.cui  
	 	and umls_concept_s_type.sui = umls_semantic_type.sui 
	 	and umls_semantic_type.sui = umls_s_type_s_group.sui
	 	and umls_s_type_s_group.abbr  = umls_semantic_group.abbr
	 	group by umls_semantic_group.name;

	select umls_semantic_type.name, count(*) 
	from conno_posts_clean, conno_posts_tags_clean,conno_tags_clean,term_exactM_concept, umls_semantic_type, umls_concept_s_type 
	where pmid > 0 and conno_posts_clean.id = post_id and conno_tags_clean.id = tag_id and conno_tags_clean.mesh_descriptor_id = 'none' and term = value and term_exactM_concept.cui!='none'
	and term_exactM_concept.cui = umls_concept_s_type.cui and umls_concept_s_type.sui = umls_semantic_type.sui 
	group by umls_semantic_type.name;

	select umls_semantic_group.name, count(*) 
	from conno_posts_clean, conno_posts_tags_clean,conno_tags_clean,term_exactM_concept, umls_semantic_type, umls_concept_s_type, umls_s_type_s_group , umls_semantic_group
	where pmid > 0 and conno_posts_clean.id = post_id and conno_tags_clean.id = tag_id and conno_tags_clean.mesh_descriptor_id = 'none' and term = value and term_exactM_concept.cui!='none'
	and term_exactM_concept.cui = umls_concept_s_type.cui and umls_concept_s_type.sui = umls_semantic_type.sui 
	and umls_semantic_type.sui = umls_s_type_s_group.sui and umls_s_type_s_group.abbr  = umls_semantic_group.abbr
	group by umls_semantic_group.name;

	select umls_semantic_group.name, count(*)  from conno_posts_clean, conno_posts_tags_clean,conno_tags_clean,term_exactM_concept, umls_semantic_type, umls_concept_s_type, umls_s_type_s_group, umls_semantic_group where pmid > 0 and conno_posts_clean.id = post_id and conno_tags_clean.id = tag_id and conno_tags_clean.mesh_descriptor_id = 'none' and term = value and term_exactM_concept.cui!='none' and term_exactM_concept.cui = umls_concept_s_type.cui and umls_concept_s_type.sui = umls_semantic_type.sui  and umls_semantic_type.sui = umls_s_type_s_group.sui and umls_s_type_s_group.abbr  = umls_semantic_group.abbr group by umls_semantic_group.name;
	select umls_semantic_group.name, count(distinct term)  from conno_posts_clean, conno_posts_tags_clean,conno_tags_clean,term_exactM_concept, umls_semantic_type, umls_concept_s_type, umls_s_type_s_group, umls_semantic_group where pmid > 0 and conno_posts_clean.id = post_id and conno_tags_clean.id = tag_id and conno_tags_clean.mesh_descriptor_id = 'none' and term = value and term_exactM_concept.cui!='none' and term_exactM_concept.cui = umls_concept_s_type.cui and umls_concept_s_type.sui = umls_semantic_type.sui  and umls_semantic_type.sui = umls_s_type_s_group.sui and umls_s_type_s_group.abbr  = umls_semantic_group.abbr group by umls_semantic_group.name;

select umls_semantic_type.name, term from conno_posts_clean, conno_posts_tags_clean,conno_tags_clean,term_exactM_concept, umls_semantic_type, umls_concept_s_type where pmid > 0 and conno_posts_clean.id = post_id and conno_tags_clean.id = tag_id and conno_tags_clean.mesh_descriptor_id = 'none' and term = value and term_exactM_concept.cui!='none' and term_exactM_concept.cui = umls_concept_s_type.cui and umls_concept_s_type.sui = umls_semantic_type.sui  group by umls_semantic_type.name;
select distinct(term) from conno_posts_clean, conno_posts_tags_clean,conno_tags_clean,term_exactM_concept, umls_semantic_type, umls_concept_s_type where pmid > 0 and conno_posts_clean.id = post_id and conno_tags_clean.id = tag_id and conno_tags_clean.mesh_descriptor_id = 'none' and term = value and term_exactM_concept.cui!='none' and term_exactM_concept.cui = umls_concept_s_type.cui and umls_concept_s_type.sui = umls_semantic_type.sui  and umls_semantic_type.name= 'Age Group';

select distinct(term) from conno_posts_clean, conno_posts_tags_clean,conno_tags_clean,term_exactM_concept, umls_semantic_type, umls_concept_s_type where pmid > 0 and conno_posts_clean.id = post_id and conno_tags_clean.id = tag_id and conno_tags_clean.mesh_descriptor_id = 'none' and term = value and term_exactM_concept.cui!='none' and term_exactM_concept.cui = umls_concept_s_type.cui and umls_concept_s_type.sui = umls_semantic_type.sui;

select umls_semantic_group.name, count(distinct mesh2008_descriptor.descriptor_id) from mesh2008_descriptor, descriptor_concept, umls_concept_s_type, umls_s_type_s_group, umls_semantic_group, umls_semantic_type where mesh2008_descriptor.descriptor_id = descriptor_concept.descriptor_id and descriptor_concept.cui = umls_concept_s_type.cui and umls_concept_s_type.sui = umls_semantic_type.sui and umls_semantic_type.sui = umls_s_type_s_group.sui and umls_s_type_s_group.abbr  = umls_semantic_group.abbr  group by umls_semantic_group.name;

	 *
	 */
	
	public String toString(){
		String o = term;
		for(Concept concept : concepts){
			o+=" "+concept.getCUI()+":"+concept.getCN();
		}
		return o;
	}

}
